/**
 Brainfuck-Robots Bluetooth App
 Copyright (C) <2014>  <Simon Grafenhorst>

 This file is part of the Brainfuck-Robots Bluetooth App.

 The Brainfuck-Robots Bluetooth App is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 The Brainfuck-Robots Bluetooth App is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with the Brainfuck-Robots Bluetooth App.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.brainfuckrobots.bluetooth;

import android.support.v4.app.FragmentActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.util.ArrayList;

import de.brainfuckrobots.bluetooth.sensors.Sensors;

public class MainActivity extends FragmentActivity {

    private final int BT_ENABLE = 1;
    private String tag = "MainActivity";
    private ChooseDeviceDialog deviceDialog;
    private DeviceReceiver deviceReceiver;
    private ConnectThread connectThread;
    private BluetoothAdapter adapter;
    private static MainActivity instance;
    private CommunicationThread communicationThread;
    private Sensors sensors;

    class DeviceReceiver extends BroadcastReceiver {
        ArrayList<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();

        public void resetDevices() {
            devices = new ArrayList<BluetoothDevice>();
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Log.i(action, "found bluetooth device: " + device.getName());
                boolean alreadyShown = false;
                for (int i = 0; i < devices.size(); i++) {
                    if (devices.get(i).getAddress().equals(device.getAddress())) {
                        alreadyShown = true;
                    }
                }
                if (!alreadyShown && device.getName() != null && device.getName().contains("Roboter")) {
                    devices.add(device);
                    try {
                        openDeviceDialog(devices);
                    } catch (Exception e) {
                        Log.i(action, e.toString());
                    }
                }
            }
        }
    }

    ;


    public static MainActivity getContext() {
        return instance;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        instance = this;
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_main);
        adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
            Log.e(tag, "adapter is null");
            Toast toast = Toast.makeText(getContext(), "No BluetoothModule found", Toast.LENGTH_LONG);
            toast.show();
            finish();
        }
        deviceReceiver = new DeviceReceiver();
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(deviceReceiver, filter);
        sensors = new Sensors();
        super.onCreate(savedInstanceState);
    }

    private void enableBluetooth() {
        Log.i(tag, "trying to enable bluetooth");
        Intent enableBtIntent = new Intent(
                BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, BT_ENABLE);
    }

    private void openDeviceDialog(ArrayList<BluetoothDevice> devices) {
        if (deviceDialog != null) {
            if (deviceDialog.getShowsDialog()) {
                deviceDialog.dismiss();
            }
        }
        deviceDialog = new ChooseDeviceDialog();
        deviceDialog.setDevices(devices);
        deviceDialog.show(getSupportFragmentManager(), "deviceDialog");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onResume() {
        Log.i(tag, "resume");
        super.onResume();
        discover(null);
    }

    @Override
    public void onPause() {
        super.onPause();
        if (connectThread != null) {
            connectThread.cancel();
        }
        if (deviceReceiver != null) {
            deviceReceiver.resetDevices();
        }
        BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
    }

    @Override
    public void onDestroy() {
        BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
        unregisterReceiver(deviceReceiver);
        super.onDestroy();
    }

    public void discover(View v) {
        if (connectThread != null) {
            connectThread.cancel();
        }
        if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
            enableBluetooth();
        }
        BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
        BluetoothAdapter.getDefaultAdapter().startDiscovery();
        deviceReceiver.resetDevices();
        if(deviceDialog != null){
            if(!deviceDialog.isVisible()){
                openDeviceDialog(new ArrayList<BluetoothDevice>());
            }
        } else{
            openDeviceDialog(null);
        }
        Log.i(tag, "restartet bluetooth discovery");
    }

    public void connect(BluetoothDevice device) {
        Log.i(tag, "trying to connect");
        connectThread = new ConnectThread(device);
        if (((ProgressBar) findViewById(R.id.progress_circle)) != null) {
            ((ProgressBar) findViewById(R.id.progress_circle)).setVisibility(View.VISIBLE);
        }
        connectThread.start();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == BT_ENABLE) {
            if (resultCode == RESULT_CANCELED) {
                Log.e(tag, "Bluetooth activation cancelled");
                finish();
            }
        }
        super.onActivityResult(requestCode, resultCode, data); //Calls onResume
    }

    public void shoot(View v) {
        Log.i(tag, "Shooting");
        if (communicationThread != null) {
            communicationThread.setShoot(true);
        } else {
            Log.e(tag, "CommunicationThread is null");
        }
    }

    public void useSensors(View v) {
        if (((CompoundButton) v).isChecked()) {
            sensors.registerOrientationListener();
        } else {
            sensors.unregisterOrientationListener();
        }
    }

    public void calibrateSensors(View v) {
        sensors.setOffset();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
            shoot(null);
        }
        return true;
    }

    public void setCommunicationThread(CommunicationThread communicationThread) {
        this.communicationThread = communicationThread;
        if (communicationThread == null) {
            Log.e(tag, "Could not connect fast enough");
            Toast toast = Toast.makeText(getContext(), R.string.notConnectToast, Toast.LENGTH_LONG);
            toast.show();
            discover(null);
        }
    }

    public void showToast(int text){
        Toast toast = Toast.makeText(getContext(), text, Toast.LENGTH_LONG);
        toast.show();
    }

}
